//
//  LYRemotePeripheral.swift
//  RxSwift_Practice
//
//  Created by 李永彬 on 2020/4/28.
//  Copyright © 2020 李永彬. All rights reserved.
//

import Foundation
import CoreBluetooth

enum LYBDChannel: Int {
    case LYBDChannel8001
    case LYBDChannel8002
    case LYBDChannel8003
    case LYBDChannel8004
}

public class LYRemotePeripheral: LYRemotePeer, LYCBPeripheralDelegate {
    
    internal var characteristicData: CBCharacteristic?
    internal var peripheral: CBPeripheral?
  
    internal var characteristic8001: CBCharacteristic!
    internal var characteristic8002: CBCharacteristic!
    private var peripheralDelegateProxy: LYCBPeripheralDelegateProxy!
    
    var sendDataModel: LYBluetoothData?
    

    // MARK: Initialization

    public init(identifier: UUID, peripheral: CBPeripheral?) {
        super.init(identifier: identifier)
        self.peripheralDelegateProxy = LYCBPeripheralDelegateProxy(delegate: self)
        self.peripheral = peripheral
    }
    
    func writeValue(dataModel: LYBluetoothData, channel: LYBDChannel) {
        
        if dataModel.type == .LYBlueToothdataTypeAddressBook
        {
//            self.addressBookDataModel = dataModel;
        }
        else if dataModel.type == .LYBlueToothdataTypeMedia
        {
//            self.responseDataModel = dataModel;
        }
        else
        {
            self.sendDataModel = dataModel;
            
        }
        
        switch channel {
        case .LYBDChannel8001:

            self.sendData(bluetoothData: dataModel, characteristic: characteristic8001)
            dataModel.state = .LYBluetoothDataStateSending
            
            guard self.characteristic8002 != nil else {
                return
            }
            
            if self.configuration!.needToSend03EndCMD {
                self.writeEndOfDataModel(dataModel: dataModel)
            }
            else
            {
                dataModel.state = .LYBluetoothDataStateSent
            }

        default:
            break
        }
    }
    
    func writeEndOfDataModel(dataModel: LYBluetoothData) {
        
        delay(0.1) {
            let bytes:[UInt8] = [0x03]
            self.peripheral?.writeValue(Data(bytes: bytes, count: 1), for: self.characteristic8002, type: .withoutResponse)
            dataModel.state = .LYBluetoothDataStateSent
        }
    }
    
    public func sendData(bluetoothData: LYBluetoothData , characteristic: CBCharacteristic) {
        
        self.peripheral?.writeValue(bluetoothData.sendData!, for: characteristic, type: .withResponse)
    }
    
    // MARK: Internal Functions
    
    internal func discoverServices() {
        
        if self.peripheral?.services != nil {
            peripheral(self.peripheral!, didDiscoverServices: nil)
            return
        }
        
        self.peripheral?.discoverServices(configuration?.servicesArray)
    }
    
    internal func unsubscribe() {
        guard self.peripheral?.services != nil else {
            return
        }
        for service in self.peripheral!.services! {
            guard service.characteristics != nil else {
                continue
            }
            for characteristic in service.characteristics! {
                self.peripheral?.setNotifyValue(false, for: characteristic)
            }
        }
    }

    internal func prepareForConnection() {
        self.peripheral?.delegate = peripheralDelegateProxy
    }
    
    // MARK: LYCBPeripheralDelegate
    func peripheralDidUpdateName(_ peripheral: CBPeripheral) {
        
    }
    
    func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
        for service: CBService in peripheral.services! {
            print("外设中的服务有：\(service)")
            peripheral.discoverCharacteristics(configuration?.characteristicArray, for: service)
        }
    }
    
    func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
        
        guard error == nil else {
            return
        }
        
        if service.uuid.uuidString.isEqual("6006") {
            
            for characteristic:CBCharacteristic in service.characteristics! {
                print("外设中的特征有：\(characteristic)")
                
                if characteristic.uuid.uuidString.isEqual("8002") {
                    //订阅
                    peripheral.setNotifyValue(true, for: characteristic)
                    self.characteristic8002 = characteristic
                }
                
                if characteristic.uuid.uuidString.isEqual("8001") {
                    self.characteristic8001 = characteristic
                }
            }
        }
        
        if service.uuid.uuidString.isEqual("7006") {
            for characteristic:CBCharacteristic in service.characteristics! {
                
                if characteristic.uuid.uuidString.isEqual("8004") {
                    //订阅
                    peripheral.setNotifyValue(true, for: characteristic)
                }
                
                if characteristic.uuid.uuidString.isEqual("8003") {
                                   
                }
            }
        }
        
        if service.uuid.uuidString.isEqual("180D") {
            for characteristic:CBCharacteristic in service.characteristics! {
                
                if characteristic.uuid.uuidString.isEqual("2A37") {
                                   
//                    //读取特征里的数据
//                    peripheral.readValue(for: characteristic)
                    //订阅
                    peripheral.setNotifyValue(true, for: characteristic)
                }
            }
        }
        
    }
    
    func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
        if let error = error {
            print("订阅失败: \(error)")
            self.sendDataModel?.state = .LYBluetoothDataStateReciveFailed
            return
        }
          
        if characteristic.isNotifying {
            if characteristic.uuid.uuidString.isEqual("8002") {
                print("订阅成功",characteristic.value ?? 0)
                self.sendDataModel?.state = .LYBluetoothDataStateRecived

                self.sendDataModel?.receivedData = characteristic.value!
            }
            
        } else {
            print("取消订阅")
        }
    }
    
    func peripheral(_ peripheral: CBPeripheral, didWriteValueFor descriptor: CBDescriptor, error: Error?) {
        
    }
    
    func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
        print("发送数据成功回调")
    }
    
    func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) {
        print("订阅状态改变",characteristic)
    }
}
